# Utilities of System
#
# Copyright (C) 2010 Yotam Medini <yotam.medini@gmail.com>
#
# This file is part of Gupicasa.
#
# Gupicasa is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Gupicasa is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Gupicasa.  If not, see <http://www.gnu.org/licenses/>.


import dircache
import os
import pwd
import shutil
import sys
import stat
import time

# local
import debug


def strnow():
    "Return current time as yyyy/mm/dd:HH:MM:SS"
    now = int(time.time())
    nowlocal = time.localtime(now)
    lta = time.localtime(now)
    s = "%d/%02d/%02d:%02d:%02d:%02d" % lta[0:6]
    return s


def myuname():
    pw = pwd.getpwuid(os.getuid())
    return pw.pw_name


def isstat(en, predicate):
    e = False
    try:
        s = os.stat(en)
        e = predicate(s[stat.ST_MODE])
    except:
        e = False
    return e


def fexist(fn):
    "Check if fn exists as regular file"
    return isstat(fn, stat.S_ISREG)


def dexist(dn):
    "Check if dn exists as a directory"
    return isstat(dn, stat.S_ISDIR)


def dir_empty(dn):
    de = False
    if dexist(db):
        de = len(dircache.listdir(db)) == 0
    return de


def unlink(fn):
    try:
        os.unlink(fn)
    except:
        pass


# Inspired by
# http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
def which(prog_basename):
    prog_fullpath = None
    path_dirs = os.environ["PATH"].split(os.pathsep)
    di = 0
    while prog_fullpath is None and di < len(path_dirs):
        x = "%s/%s" % (path_dirs[di], prog_basename)
        if fexist(x) and os.access(x, os.X_OK):
            prog_fullpath = x
        di += 1
    return prog_fullpath


class _DirClear:

    def __init__(self):
        self.excinfo = None


    def on_eror(self, func, path, excinfo):
        if self.excinfo is None:
            self.excinfo = excinfo


def dir_remove(dn):
    "Remove directory"
    dc = _DirClear()
    shutil.rmtree(dn, False, dc.on_eror)
    s = None
    if dc.excinfo is not None:
        # sys.stdout.write("len(excinfo)=%d\n" % len(dc.excinfo))
        s = str(dc.excinfo[1])
    return s


def dir_clear(dn):
    "Make a fresh directory"
    debug.log("dn=%s" % dn)
    err = dir_remove(dn)
    debug.log("dn=%s" % dn)
    if err is None:
        os.mkdir(dn)
    return err


if __name__ == '__main__':
    def test_dirclear(dn):
        dn = sys.argv[1]
        fn = dn + "/.unseen"
        try:
            os.mkdir(dn)
        except:
            pass
        try:
            f = open(fn, "w")
            f.write("bla\n")
            f.close()
            os.chmod(fn, 0)
        except:
            pass
        s = dir_clear(dn)
        if s is not None:
            sys.stderr.write("dir_clear: %s\n" % s)

    rc = 0
    if sys.argv[1] == 'dirclear':
        test_dirclear(sys.argv[2])
    elif sys.argv[1] == 'which':
        for f in sys.argv[2:]:
            a = which (f)
            sys.stdout.write("which(%s) = %s\n" % (f, a))
    else:
        sys.stderr.write("Unkown test\n")
        rc = 1
    sys.exit(rc)

